package com.layblog.common.template;

import freemarker.core.Environment;
import freemarker.template.TemplateDirectiveBody;
import freemarker.template.TemplateDirectiveModel;
import freemarker.template.TemplateException;
import freemarker.template.TemplateModel;

import java.io.IOException;
import java.util.Map;


/**
 * 要在Freemarker实现自定义的标签，主要是靠TemplateDirectiveModel接口，如字面上的意思：模板指令模型，
 * 只要就是用来扩展自定义的指令(和freemarker的宏类似)，TemplateDirectiveModel是一个接口，类中只有一个
 * execute方法供使用者实现，而我们要做的就是通过实现execute方法，实现自定义标签的功能。当页面模板中使用
 * 自定义标签时，会自动调用该方法。
 *
 * @Author 林必昭
 * @Date 2021/7/7 11:45
 */
public abstract class TemplateDirective implements TemplateDirectiveModel {
    protected static String RESULT = "result";
    protected static String RESULTS = "results";

    protected static String SIGN_RESULT = "signResult";

    /**
     * 实现execute方法，实现自定义变迁的功能，当使用自定义标签，就会自动调用这个方法
     *
     * @param env        模板处理期间的运行环境
     * @param parameters 传递给自定义标签的参数
     * @param loopVars   循环替代变量
     * @param body       表示自定义标签中嵌套的内容<@myDirective/>或者<@myDirective></myDirective >
     * @throws TemplateException
     * @throws IOException
     */
    @Override
    public void execute(Environment env, Map parameters, TemplateModel[] loopVars, TemplateDirectiveBody body) throws TemplateException, IOException {
        try {
            execute(new DirectiveHandler(env, parameters, loopVars, body));
        } catch (IOException e) {
            throw e;
        } catch (Exception e) {
            throw new TemplateException(e, env);
        }
    }

    abstract public String getName();

    /**
     * 这里在封装一层，将execute的参数封装成DirectiveHandler，我们直接使用handler很方便
     *
     * @param handler
     * @throws Exception
     */
    abstract public void execute(DirectiveHandler handler) throws Exception;

}
